package com.TeacherInfoServer.common.service.Impl;

import com.TeacherInfoServer.common.Result;
import com.TeacherInfoServer.converter.TalentLevelConverter;
import com.TeacherInfoServer.exception.JobNumberNotExistException;
import com.TeacherInfoServer.mapper.TalentTitleMapper;
import com.TeacherInfoServer.pojo.DTO.AddTalentTitleDTO;
import com.TeacherInfoServer.pojo.DTO.SearchDTO.TalentTitleSearchDTO;
import com.TeacherInfoServer.pojo.DTO.UpdateTalentTitleDTO;
import com.TeacherInfoServer.pojo.entity.TalentTitle;
import com.TeacherInfoServer.pojo.vo.TalentTitleListVo;
import com.TeacherInfoServer.pojo.vo.TalentTitleVo;
import com.TeacherInfoServer.common.service.TalentTitleService;
import com.TeacherInfoServer.common.service.TeacherService;
import com.TeacherInfoServer.utils.HttpServletUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class TalentTitleServiceImpl extends ServiceImpl<TalentTitleMapper, TalentTitle> implements TalentTitleService {
    @Autowired
    private TalentTitleMapper talentTitleMapper;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private TalentLevelConverter talentLevelConverter;

    @Override
    @Transactional
    public Result<Map<String, Integer>> addOne(AddTalentTitleDTO addTalentTitleDTO) {
        if (teacherService.getOne(addTalentTitleDTO.getTeacherId()).getData() != null){
            TalentTitle talentTitle =
                    new TalentTitle(null,
                            addTalentTitleDTO.getTeacherId(),
                            addTalentTitleDTO.getTitleName(),
                            talentLevelConverter.convertToJavaData(addTalentTitleDTO.getTitleLevel()),
                            addTalentTitleDTO.getObtainDate(),1,null);
            Integer record = talentTitleMapper.insert(talentTitle);
            Map<String,Integer> map = new HashMap<>();
            map.put("record",record);
            return Result.success(map);
        } else {
            throw new JobNumberNotExistException();
        }
    }

    @Override
    @Transactional
    public Result<TalentTitleListVo> getList(Long pageNumber, Long pageSize) {
        Page<TalentTitle> page = new Page<>(pageNumber,pageSize);
        List<TalentTitle> talentTitleList = talentTitleMapper.selectPageWithTeacher(page);
        List<TalentTitleVo> talentTitleVoList = getTalentTitleVoList(talentTitleList);
        TalentTitleListVo talentTitleListVo =
                new TalentTitleListVo(page.getCurrent(),
                        page.getSize(),
                        page.getPages(),
                        page.getTotal(),
                        talentTitleVoList);
        return Result.success(talentTitleListVo);
    }

    @Override
    public Map<String,Object> searchTalentTitleList(TalentTitleSearchDTO talentTitleSearchDTO) {
        Page<TalentTitleVo> page = new Page<>(talentTitleSearchDTO.getPages(), talentTitleSearchDTO.getSize());
        talentTitleMapper.searchTalentTitleByPage(page, talentTitleSearchDTO);
        Map<String, Object> data = new HashMap<>();
        data.put("totals", page.getTotal());
        data.put("currentPages", page.getCurrent());
        data.put("pageNumber", page.getPages());
        data.put("rows", page.getRecords());
        return data;
    }

    @Override
    @Transactional
    public Result<TalentTitleListVo> getOneList(Long pageNumber, Long pageSize, String teacherId) {
        Page<TalentTitle> page = new Page<>(pageNumber,pageSize);
        List<TalentTitle> talentTitleList = talentTitleMapper.selectPageWithTeacher(page);
        List<TalentTitleVo> talentTitleVoList = getTalentTitleVoList(talentTitleList);
        TalentTitleListVo talentTitleListVo =
                new TalentTitleListVo(page.getCurrent(),
                        page.getSize(),
                        page.getPages(),
                        page.getTotal(),
                        talentTitleVoList);
        return Result.success(talentTitleListVo);
    }

    @Override
    public void export(HttpServletResponse response, String fileName) throws IOException {
        HttpServletUtil.setExportResponse(response,fileName);
        List<TalentTitle> talentTitleList = talentTitleMapper.selectPageWithTeacher(null);
        List<TalentTitleVo> talentTitleVoList = getTalentTitleVoList(talentTitleList);
        EasyExcel.write(response.getOutputStream(), TalentTitleVo.class).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(talentTitleVoList);
    }

    @Override
    @Transactional
    public Result<Map<String, Integer>> deleteBatch(Integer[] ids) {
        Integer record = talentTitleMapper.deleteBatchIds(Arrays.asList(ids));
        Map<String, Integer> map = new HashMap<>();
        map.put("record", record);
        return Result.success(map);
    }

    @Override
    @Transactional
    public Result<Map<String, Integer>> updateOne(UpdateTalentTitleDTO updateTalentTitleDTO) {
        if (teacherService.getOne(updateTalentTitleDTO.getTeacherId()).getData() != null){
            LambdaUpdateWrapper<TalentTitle> wrapper = new LambdaUpdateWrapper<>();
            Integer record = talentTitleMapper.update(null,wrapper.eq(TalentTitle::getId, updateTalentTitleDTO.getId())
                    .set(TalentTitle::getTeacherId, updateTalentTitleDTO.getTeacherId())
                    .set(TalentTitle::getTitleName, updateTalentTitleDTO.getTitleName())
                    .set(TalentTitle::getTitleLevelId, talentLevelConverter.convertToJavaData(updateTalentTitleDTO.getTitleLevel()))
                    .set(TalentTitle::getObtainDate, updateTalentTitleDTO.getObtainDate()));
            Map<String, Integer> map = new HashMap<>();
            map.put("record", record);
            return Result.success(map);
        } else {
            throw new JobNumberNotExistException();
        }
    }

    private List<TalentTitleVo> getTalentTitleVoList(List<TalentTitle> talentTitleList){
        return talentTitleList.stream()
                .map(talentTitle -> new TalentTitleVo(
                        talentTitle.getId(),
                        talentTitle.getTeacherId(),
                        talentTitle.getTeacher().getTeacherName(),
                        talentTitle.getTitleName(),
                        talentLevelConverter.convertToExcelData(talentTitle.getTitleLevelId()),
                        talentTitle.getObtainDate()
                ))
                .collect(Collectors.toList());
    }
}
